package io.wongxd.solution.compose.helper

import android.graphics.Bitmap
import android.graphics.Canvas
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.PixelCopy
import android.view.View
import android.view.Window
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.layout.boundsInRoot
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import io.wongxd.solution.logger.WLogUtil
import io.wongxd.solution.util.ext.findWindow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import kotlin.math.roundToInt

@Composable
fun CaptureCompose(
    needCapture: Boolean,
    captureDelayMs: Long = 3000L,
    afterResult: (Bitmap) -> Unit,
    content: @Composable () -> Unit
) {


    fun captureView(
        view: View,
        window: Window,
        dstBmp: Bitmap,
        bitmapCallback: (Bitmap) -> Unit
    ) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            WLogUtil.d("captureView version O 以上")
            // 高于 O 的，使用 PixelCopy
            PixelCopy.request(
                window,
                dstBmp,
                {
                    if (it == PixelCopy.SUCCESS) {
                        WLogUtil.d("captureView 获取到 bitmap")
                        bitmapCallback.invoke(dstBmp)
                    } else {
                        WLogUtil.d("captureView 未获取到 bitmap, copyResult = $it")
                    }
                },
                Handler(Looper.getMainLooper())
            )
        } else {
            WLogUtil.d("captureView version O 以下")
            val canvas = Canvas(dstBmp)
            view.draw(canvas)
            canvas.setBitmap(null)
            bitmapCallback.invoke(dstBmp)
        }
    }

    var capturingViewBounds by remember { mutableStateOf<Rect?>(null) }

    val context = LocalContext.current
    val view = LocalView.current

    Box(modifier = Modifier
        .fillMaxSize()
        .onGloballyPositioned {
            capturingViewBounds = it.boundsInRoot()
        }) {
        content()
    }

    LaunchedEffect(key1 = Unit, block = {
        withContext(Dispatchers.IO) {
            delay(captureDelayMs)

            if (needCapture.not()) return@withContext

            val bounds = capturingViewBounds ?: return@withContext
            val bitmap = Bitmap.createBitmap(
                bounds.width.roundToInt(), bounds.height.roundToInt(),
                Bitmap.Config.ARGB_8888
            )
            withContext(Dispatchers.Main) {
                captureView(view, context.findWindow()!!, bitmap) {
                    afterResult.invoke(it)
                }
            }
        }
    })


}